home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Cafe 3
/
Visual Cafe 3.ISO
/
Vcafe
/
JFC.bin
/
MetalTabbedPaneUI.java
< prev
next >
Wrap
Text File
|
1998-06-30
|
22KB
|
661 lines
/*
* @(#)MetalTabbedPaneUI.java 1.14 98/04/10
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing.plaf.metal;
import com.sun.java.swing.*;
import com.sun.java.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.plaf.*;
import java.io.Serializable;
import com.sun.java.swing.plaf.basic.BasicTabbedPaneUI;
/**
* The Metal subclass of BasicTabbedPaneUI.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @version 1.14 04/10/98
* @author Tom Santos
*/
public class MetalTabbedPaneUI extends BasicTabbedPaneUI {
protected static Insets tabsOnTopTabAreaInsets = new Insets(4,2,0,6);
protected static Insets tabsOnLeftTabAreaInsets = new Insets(6,4,0,0);
protected static Insets tabsOnBottomTabAreaInsets = new Insets(0,2,4,6);
protected static Insets tabsOnRightTabAreaInsets = new Insets(0,0,6,4);
protected int minTabWidth = 40;
protected Color selectColor;
protected Color selectHighlight;
public static ComponentUI createUI( JComponent x ) {
return new MetalTabbedPaneUI();
}
protected void installDefaults( JComponent c ) {
JTabbedPane pane = (JTabbedPane)c;
super.installDefaults(c);
selectColor = UIManager.getColor("TabbedPane.selected");
selectHighlight = UIManager.getColor("TabbedPane.selectHighlight");
}
protected void paintTabBorder( Graphics g, JTabbedPane pane, int tabPlacement,
int tabIndex, int x, int y, int w, int h,
boolean isSelected) {
int bottom = y + (h-1);
int right = x + (w-1);
switch ( tabPlacement ) {
case LEFT:
paintLeftTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
break;
case BOTTOM:
paintBottomTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
break;
case RIGHT:
paintRightTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
break;
case TOP:
default:
paintTopTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
}
}
protected void paintTopTabBorder( JTabbedPane pane, int tabIndex, Graphics g,
int x, int y, int w, int h,
int btm, int rght,
boolean isSelected ) {
int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
int firstIndex = tabRuns[ currentRun ];
//
// Paint Gap
//
if ( shouldFillGap( pane, currentRun, tabIndex, x, y ) ) {
g.translate( x, y );
g.setColor( getColorForGap( pane, currentRun, x, y + 1 ) );
g.fillRect( 1, 0, 5, 3 );
g.fillRect( 1, 3, 2, 2 );
g.translate( -x, -y );
}
g.translate( x, y );
int bottom = h - 1;
int right = w - 1;
//
// Paint Border
//
g.setColor( tabDarkShadow );
// Paint slant
g.drawLine( 1,5 , 6,0 );
// Paint top
g.drawLine( 6,0 , right,0 );
// Paint right
if ( tabIndex == lastIndex ) {
g.drawLine( right,1 , right,bottom );
}
// Paint left
if ( tabIndex != tabRuns[ runCount - 1 ] ) {
g.drawLine( 0,0 , 0,bottom );
} else {
g.drawLine( 0,6 , 0,bottom );
}
//
// Paint Highlight
//
g.setColor( isSelected ? selectHighlight : tabHighlight );
// Paint slant
g.drawLine( 1,6 , 6,1 );
// Paint top
g.drawLine( 6,1 , right,1 );
// Paint left
g.drawLine( 1,6 , 1,bottom );
if ( tabIndex == firstIndex && tabIndex != tabRuns[ runCount - 1 ] ) {
g.setColor( pane.getSelectedIndex() == tabRuns[ currentRun + 1 ] ? selectHighlight : tabHighlight );
g.drawLine( 1,0 , 1,4 );
}
g.translate( -x, -y );
}
protected boolean shouldFillGap( JTabbedPane pane, int currentRun, int tabIndex, int x, int y ) {
boolean result = false;
if ( currentRun == runCount - 2 ) { // If it's the second to last row.
Rectangle lastTabBounds = getTabBounds( pane, pane.getTabCount() - 1 );
int lastTabRight = lastTabBounds.x + lastTabBounds.width - 1;
if ( lastTabRight > getTabBounds( pane, tabIndex ).x + 2 ) {
return true;
}
} else {
result = currentRun != runCount - 1;
}
return result;
}
protected Color getColorForGap( JTabbedPane pane, int currentRun, int x, int y ) {
final int shadowWidth = 4;
int selectedIndex = pane.getSelectedIndex();
int startIndex = tabRuns[ currentRun + 1 ];
int endIndex = lastIndexInRun( currentRun + 1, pane.getTabCount() );
int tabOverGap = -1;
// Check each tab in the row that is 'on top' of this row
for ( int i = startIndex; i <= endIndex; ++i ) {
Rectangle tabBounds = getTabBounds( pane, i );
int tabLeft = tabBounds.x;
int tabRight = (tabBounds.x + tabBounds.width) - 1;
// Check to see if this tab is over the gap
if ( tabLeft + 1 < x && tabRight - shadowWidth > x ) {
return selectedIndex == i ? selectColor : pane.getBackgroundAt( i );
}
}
return pane.getBackground();
}
protected void paintLeftTabBorder( JTabbedPane pane, int tabIndex, Graphics g,
int x, int y, int w, int h,
int btm, int rght,
boolean isSelected ) {
int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
int firstIndex = tabRuns[ currentRun ];
g.translate( x, y );
int bottom = h - 1;
int right = w - 1;
//
// Paint part of the tab above
//
if ( tabIndex != firstIndex ) {
g.setColor( pane.getSelectedIndex() == tabIndex - 1 ?
selectColor :
pane.getBackgroundAt( tabIndex - 1 ) );
g.fillRect( 2, 0, 4, 3 );
g.drawLine( 2, 3, 2, 3 );
}
//
// Paint Highlight
//
g.setColor( isSelected ? selectHighlight : tabHighlight );
// Paint slant
g.drawLine( 1, 6, 6, 1 );
// Paint top
g.drawLine( 6, 1, right, 1 );
// Paint left
g.drawLine( 1, 6, 1, bottom );
if ( tabIndex != firstIndex ) {
g.setColor( pane.getSelectedIndex() == tabIndex - 1 ?
selectHighlight :
tabHighlight );
g.drawLine( 1, 0, 1, 4 );
}
//
// Paint Border
//
g.setColor( tabDarkShadow );
// Paint slant
g.drawLine( 1, 5, 6, 0 );
// Paint top
g.drawLine( 6, 0, right, 0 );
// Paint left
if ( tabIndex != firstIndex ) {
g.drawLine( 0, 0, 0, bottom );
} else {
g.drawLine( 0, 6, 0, bottom );
}
// Paint bottom
if ( tabIndex == lastIndex ) {
g.drawLine( 0, bottom, right, bottom );
}
g.translate( -x, -y );
}
protected void paintBottomTabBorder( JTabbedPane pane, int tabIndex, Graphics g,
int x, int y, int w, int h,
int btm, int rght,
boolean isSelected ) {
int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
int firstIndex = tabRuns[ currentRun ];
int bottom = h - 1;
int right = w - 1;
//
// Paint Gap
//
if ( shouldFillGap( pane, currentRun, tabIndex, x, y ) ) {
g.translate( x, y );
g.setColor( getColorForGap( pane, currentRun, x, y ) );
g.fillRect( 1, bottom - 4, 3, 5 );
g.fillRect( 4, bottom - 1, 2, 2 );
g.translate( -x, -y );
}
g.translate( x, y );
//
// Paint Border
//
g.setColor( tabDarkShadow );
// Paint slant
g.drawLine( 1, bottom - 5, 6, bottom );
// Paint bottom
g.drawLine( 6, bottom, right, bottom );
// Paint right
if ( tabIndex == lastIndex ) {
g.drawLine( right, 0, right, bottom );
}
// Paint left
if ( tabIndex != tabRuns[ runCount - 1 ] ) {
g.drawLine( 0, 0, 0, bottom );
} else {
g.drawLine( 0, 0, 0, bottom - 6 );
}
//
// Paint Highlight
//
g.setColor( isSelected ? selectHighlight : tabHighlight );
// Paint slant
g.drawLine( 1, bottom - 6, 6, bottom - 1 );
// Paint left
g.drawLine( 1, 0, 1, bottom - 6 );
if ( tabIndex == firstIndex && tabIndex != tabRuns[ runCount - 1 ] ) {
g.setColor( pane.getSelectedIndex() == tabRuns[ currentRun + 1 ] ? selectHighlight : tabHighlight );
g.drawLine( 1, bottom - 4, 1, bottom );
}
g.translate( -x, -y );
}
protected void paintRightTabBorder( JTabbedPane pane, int tabIndex, Graphics g,
int x, int y, int w, int h,
int btm, int rght,
boolean isSelected ) {
int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
int firstIndex = tabRuns[ currentRun ];
g.translate( x, y );
int bottom = h - 1;
int right = w - 1;
//
// Paint part of the tab above
//
if ( tabIndex != firstIndex ) {
g.setColor( pane.getSelectedIndex() == tabIndex - 1 ?
selectColor :
pane.getBackgroundAt( tabIndex - 1 ) );
g.fillRect( right - 5, 0, 5, 3 );
g.fillRect( right - 2, 3, 2, 2 );
}
//
// Paint Highlight
//
g.setColor( isSelected ? selectHighlight : tabHighlight );
// Paint slant
g.drawLine( right - 6, 1, right - 1, 6 );
// Paint top
g.drawLine( 0, 1, right - 6, 1 );
// Paint left
g.drawLine( 0, 1, 0, bottom );
//
// Paint Border
//
g.setColor( tabDarkShadow );
// Paint slant
g.drawLine( right - 6, 0, right, 6 );
// Paint top
g.drawLine( 0, 0, right - 6, 0 );
// Paint right
if ( tabIndex != firstIndex ) {
g.drawLine( right, 0, right, bottom );
} else {
g.drawLine( right, 6, right, bottom );
}
// Paint bottom
if ( tabIndex == lastIndex ) {
g.drawLine( 0, bottom, right, bottom );
}
g.translate( -x, -y );
}
protected void paintTabBackground( Graphics g, JTabbedPane pane, int tabPlacement,
int tabIndex, int x, int y, int w, int h, boolean isSelected ) {
int slantWidth = h / 2;
if ( isSelected ) {
g.setColor( selectColor );
} else {
g.setColor( pane.getBackgroundAt( tabIndex ) );
}
switch ( tabPlacement ) {
case LEFT:
g.fillRect(x + 5, y + 1, w - 5, h - 1);
g.fillRect( x + 2, y + 4, 3, h - 4 );
break;
case BOTTOM:
g.fillRect( x + 2, y, w - 2, h - 3 );
g.fillRect( x + 5, (y + (h - 1)) - 3, w - 5, 3 );
break;
case RIGHT:
g.fillRect(x + 1, y + 1, w - 5, h - 1);
g.fillRect( (x+(w-1)) - 3, y+5, 3, h - 1 );
break;
case TOP:
default:
g.fillRect( x + 4, y + 2, (w - 1) - 3, (h - 1) - 1 );
g.fillRect( x + 2, y + 5, 2, h - 5 );
}
}
protected Insets getTabAreaInsets( JTabbedPane pane, int tabPlacement ) {
Insets insets;
switch ( tabPlacement ) {
case LEFT:
insets = tabsOnLeftTabAreaInsets;
break;
case BOTTOM:
insets = tabsOnBottomTabAreaInsets;
break;
case RIGHT:
insets = tabsOnRightTabAreaInsets;
break;
case TOP:
default:
insets = tabsOnTopTabAreaInsets;
}
return insets;
}
/**
* Overidden to do nothing for the Java L&F.
*/
protected int calculateXNudge( JTabbedPane pane, int tabPlacement,
int tabIndex, boolean isSelected ) {
return 0;
}
/**
* Overidden to do nothing for the Java L&F.
*/
protected int calculateYNudge( JTabbedPane pane, int tabPlacement,
int tabIndex, boolean isSelected ) {
return 0;
}
public void paint( Graphics g, JComponent c ) {
JTabbedPane pane = (JTabbedPane)c;
int tabPlacement = pane.getTabPlacement();
Insets insets = c.getInsets();
Dimension size = c.getSize();
// Paint the background for the tab area
if ( pane.isOpaque() ) {
g.setColor( c.getBackground() );
switch ( tabPlacement ) {
case LEFT:
g.fillRect( insets.left, insets.top,
totalTabWidth( pane, tabPlacement, runCount ),
size.height - insets.bottom - insets.top );
break;
case BOTTOM:
int totalTabHeight = totalTabHeight( pane, tabPlacement, runCount );
g.fillRect( insets.left, size.height - insets.bottom - totalTabHeight,
size.width - insets.left - insets.right,
totalTabHeight );
break;
case RIGHT:
int totalTabWidth = totalTabWidth( pane, tabPlacement, runCount );
g.fillRect( size.width - insets.right - totalTabWidth,
insets.top, totalTabWidth,
size.height - insets.top - insets.bottom );
break;
case TOP:
default:
g.fillRect( insets.left, insets.top,
size.width - insets.right - insets.left,
totalTabHeight(pane, tabPlacement, runCount) );
paintHighlightBelowTab( pane );
}
}
super.paint( g, c );
}
protected void paintHighlightBelowTab( JTabbedPane pane ) {
}
protected void paintFocusIndicator(Graphics g, JTabbedPane pane, int tabPlacement,
Rectangle[] rects, int tabIndex,
Rectangle iconRect, Rectangle textRect,
boolean isSelected) {
if ( pane.hasFocus() && isSelected ) {
Rectangle tabRect = rects[tabIndex];
g.setColor( focus );
g.translate( tabRect.x, tabRect.y );
int right = tabRect.width - 1;
int bottom = tabRect.height - 1;
switch ( tabPlacement ) {
case RIGHT:
g.drawLine( right - 6,2 , right - 2,6 ); // slant
g.drawLine( 1,2 , right - 6,2 ); // top
g.drawLine( right - 2,6 , right - 2,bottom ); // right
g.drawLine( 1,2 , 1,bottom ); // left
g.drawLine( 1,bottom , right - 2,bottom ); // bottom
break;
case BOTTOM:
g.drawLine( 2,bottom - 6 , 6,bottom - 2 ); // slant
g.drawLine( 6,bottom - 2 , right,bottom - 2 ); // bottom
g.drawLine( 2,0 , 2,bottom - 6 ); // left
g.drawLine( 2,0 , right,0 ); // top
g.drawLine( right,0 , right,bottom - 2 ); // right
break;
case TOP:
case LEFT:
default:
g.drawLine( 2,6 , 6,2 ); // slant
g.drawLine( 2,6 , 2,bottom - 1); // left
g.drawLine( 6,2 , right,2 ); // top
g.drawLine( right,2 , right,bottom - 1 ); // right
g.drawLine( 2,bottom - 1 , right, bottom - 1 ); // bottom
}
g.translate( -tabRect.x, -tabRect.y );
}
}
protected void paintContentBorderTopEdge( Graphics g, int tabPlacement,
int selectedIndex,
int x, int y, int width, int height ) {
g.setColor( tabDarkShadow );
g.drawLine(x-1, y, width-2, y);
}
protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
int selectedIndex,
int x, int y, int w, int h) {
g.setColor( tabDarkShadow );
g.drawLine( x, y+(h-1), x+(w-1), y+(h-1) );
}
protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
int selectedIndex,
int x, int y, int w, int h) {
g.setColor( tabDarkShadow );
g.drawLine( x, y, x, y+(h-1) );
}
protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
int selectedIndex,
int x, int y, int w, int h) {
g.setColor( tabDarkShadow );
g.drawLine( x+(w-1), y, x+(w-1), y+(h-1) );
}
protected int maxTabHeight( JTabbedPane pane, FontMetrics metrics ) {
int height = metrics.getHeight();
boolean tallerIcons = false;
for ( int i = 0; i < pane.getTabCount(); ++i ) {
Icon icon = pane.getIconAt( i );
if ( icon != null ) {
if ( icon.getIconHeight() > height ) {
tallerIcons = true;
break;
}
}
}
return super.maxTabHeight( pane, metrics ) - (tallerIcons ? (spacingHeight * 2) : 0);
}
protected int getTabOverlay( JTabbedPane pane, int tabPlacement ) {
// Tab runs layed out vertically should overlap
// at least as much as the largest slant
if ( tabPlacement == LEFT || tabPlacement == RIGHT ) {
int maxTabHeight = maxTabHeight(pane);
return maxTabHeight / 2;
}
return 0;
}
protected void normalizeTabRuns( JTabbedPane pane, int tabPlacement, int tabCount,
int start, int max ) {
// Only normalize the runs for top & bottom; normalizing
// doesn't look right for Metal's vertical tabs
// because the last run isn't padded and it looks odd to have
// fat tabs in the first vertical runs, but slimmer ones in the
// last (this effect isn't noticable for horizontal tabs).
if ( tabPlacement == TOP || tabPlacement == BOTTOM ) {
super.normalizeTabRuns(pane, tabPlacement, tabCount, start, max);
}
}
// Don't rotate runs!
protected void rotateTabRuns( JTabbedPane pane, int tabPlacement, int selectedRun ) {
}
// Don't pad last run
protected boolean shouldPadRun( JTabbedPane pane, int tabPlacement, int run ) {
return runCount > 1 && run < runCount - 1;
}
// Don't pad selected tab
protected void padSelectedTab( JTabbedPane pane, int tabPlacement, int selectedIndex ) {
}
}